/*the sort function has not been implemented. all the other functions are working as expected as far as I have tested them*/
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

struct list
{
int x;
struct list *p;
};

struct list *head, *temp, *tail;
int count;

void append(int n)/*appends an element at the end of the list*/
{
temp = head;
(head->x) = n;
head  = malloc(sizeof(struct list));
(head->x) = 0;
(temp->p) = head;
temp = tail;
count++;
}

void extend()/*extends the list dynamically*/
{
int d, i;
printf("enter 1 to enter an element, 0 to exit");
scanf("%d",&d);
while (d != 0)
{
	if (d==1)
		{
		printf("enter the element of the list: ");
		scanf("%d",&i);
		append(i);
		printf("enter 1 to enter an element, 0 to exit: ");
		scanf("%d",&d);
	}
	else
	{
		printf("enter 1 to enter an element, 0 to exit: ");
		scanf("%d",&d);
	}
}
}


int pop()/*pops the last element of the list*/
{
count--;
int i;
int c;
for (i=0;i<(count);i++)
{
	temp = (temp->p);
}
c = (temp->x);
free(head);
head = temp;
(head->x)=0;
temp=tail;
return c;
}

void remove_element(int n) /*removes 1st occurence of x from the list*/
{
int i, j, flag=0;
struct list *temp1;
temp1 = temp;
for (i=0;i<count;i++)
{
	if ((temp->x) == n && i>0)
	{
		count--;
		flag++;
		(temp1->p)=(temp->p);
		free(temp);
		break;
	}
	if ((temp->x) == n && i==0)
	{
		count--;
		flag++;
		temp = (temp->p);
		free(tail);
		tail = temp;
		temp1 = temp;
		break;
	}
	else
	{
		temp1 = temp;
		temp = (temp->p);
	}
}
if (flag==0)
{printf("the element doesn't exist in the list\n");}
temp=tail;
}

int index_element(int n) /*returns the index value of x in the list*/
{
int i, flag=0, ind;
for (i=0;i<count;i++)
{
	if ((temp->x)==n)
	{
		flag=1;
		ind=i; 
		break;
	}
	else
	{
		temp=(temp->p);
	}
}
temp = tail;
if (flag==0)
{return -1;}
else
{return ind;}
}

int count_element(int n) /*counts the number of occurences of x*/
{
int i;
int val_count=0;
for (i=0;i<count;i++)
{
	if ((temp->x) == n)
	{
		val_count++;
	}
	temp = (temp->p);
}
temp=tail;
return val_count;
}

void insert(int index_val, int val) /*inserts val at index_val*/
{
int i; 
struct list *temp1;
temp1 = malloc(sizeof(struct list));
(temp1->x) = val;
for (i=0;i<(index_val-1);i++)
{
	temp = (temp->p);
}
(temp1->p) = (temp->p);
(temp ->p) = temp1;
count++;
temp = tail;
}

void reverse()/*reverses the list. uses an array of pointers equal to the number of elements in the list.*/
{
int length;
length = count;
struct list *r_p[length];
int i;
for (i=0;i<length;i++)
{
	r_p[i] = temp;
	temp = (temp->p);
}
for (i=1;i<length;i++) /*reversing the list*/
{
	(r_p[i]->p) = r_p[i-1];
}
(r_p[0]->p) = head;
tail = r_p[length-1];
temp = tail;
}

void sort()
{
}

int main()
{
head = malloc(sizeof(struct list));
temp = tail = head;
int i;
int d=1;
int var_export, index_export, func_out;
while (d!=0)
{
	printf("Enter 0 to quit and print the final list\n1 to append an element\n2 to extend the list\n3 to insert an element at a position of your choice \n4 to remove 1st occurence of a certain value from list\n5 to pop the last element from the list \n6 to find out the index value of an element\n7 to count the number of occurences of a value\n8 to sort the list in increasing order\n9 to reverse the list\n10 to print the list: ");
	scanf("%d",&d);
	if (d==1)
	{
		printf("enter the number: ");
		scanf("%d",&var_export);
		append(var_export);
	}
	if (d==2)
	{
		extend();
	}
	if (d==3)
	{
		printf("enter the number: ");
		scanf("%d",&var_export);
		printf("enter the position/index value: ");
		scanf("%d",&index_export);
		insert(index_export, var_export);
	}
	if (d==4)
	{
		printf("enter the number: ");
		scanf("%d",&var_export);
		remove_element(var_export);
	}
	if (d==5)
	{
		if (count>0)
		{
			func_out = pop();
			printf("%d\n", func_out);
		}
		else	
		{
			printf("the list does not contain any element to be popped\n");
		}
	}
	if (d==6)
	{
		printf("enter the number: ");
		scanf("%d",&var_export);
		index_export = index_element(var_export);
		if (index_export==-1)
		{
			printf("the element does not exist in the list\n");
		}
		else
		{
			printf("%d\n", index_element(var_export));
		}
	}
	if (d==7)
	{
		printf("enter the number: ");
		scanf("%d",&var_export);
		printf("%d\n",count_element(var_export));
	}
	if (d==8)
	{
		sort();
	}
	if (d==9)
	{
		reverse();
	}
	if (d==10)
	{
		for (i=0;i<count;i++)
		{
			printf("%d\n", (temp->x));
			temp = (temp->p);
		}
		temp=tail;
	}
}
for (i=0;i<count;i++)
{
	printf("%d\n", (temp->x));
	temp = (temp->p);
}
}

